package com.junzhiit.nengji.cms.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.junzhiit.nengji.bo.RoleListBO;
import com.junzhiit.nengji.cms.service.RoleService;
import com.junzhiit.nengji.cms.web.exception.RoleNotFoundException;
import com.junzhiit.nengji.cms.web.exception.ShopDefaultRoleIsExistException;
import com.junzhiit.nengji.cms.web.util.Constants;
import com.junzhiit.nengji.cms.web.util.OrderNumberUtils;
import com.junzhiit.nengji.cms.web.util.ViewObjectUtil;
import com.junzhiit.nengji.cms.web.vo.DataTablesParamVO;
import com.junzhiit.nengji.cms.web.vo.ResultVO;
import com.junzhiit.nengji.cms.web.vo.RoleAEVO;
import com.junzhiit.nengji.cms.web.vo.RoleFunctionAddVO;
import com.junzhiit.nengji.cms.web.vo.RoleListVO;
import com.junzhiit.nengji.cms.web.vo.RoleVO;
import com.junzhiit.nengji.cms.web.vo.SystemUserSessionVO;
import com.junzhiit.nengji.dao.RoleDAO;
import com.junzhiit.nengji.dao.RoleFunctionDAO;
import com.junzhiit.nengji.dao.SystemUserRoleDAO;
import com.junzhiit.nengji.dao.cache.RoleCacheDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Role;
import com.junzhiit.nengji.model.RoleFunction;
import com.junzhiit.nengji.model.SystemUserRole;
import com.junzhiit.nengji.model.enums.DefaultType;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.IsChainStatus;
import com.junzhiit.nengji.model.enums.LoginType;
import com.junzhiit.nengji.model.enums.ShopIsPlatform;
import com.junzhiit.nengji.model.enums.SystemUserType;

@Service
public class RoleServiceImpl extends BaseServiceImpl implements RoleService {

	@Autowired
	private RoleDAO roleDAO;

	@Autowired
	private RoleCacheDAO roleCacheDAO;

	@Autowired
	private SystemUserRoleDAO systemUserRoleDAO;

	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;

	@Autowired
	private RoleFunctionDAO roleFunctionDAO;

	@Override
	public Map<String, Object> findAll(DataTablesParamVO dtp, RoleVO roleVO) {
		Role role = new Role();
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO.getHash(DIYKey.getSessionHashKey(roleVO.getSessionId()),
				SystemUserSessionVO.class);
		if (StringUtils.isBlank(roleVO.getSystemId())) {
			roleVO.setSystemId(Constants.ROOT_VALUE);
		}
		BeanUtils.copyProperties(roleVO, role);
		if(systemUserSessionVO.getLoginType()==LoginType.SHOP.toIntType() && systemUserSessionVO.getIsChain()==IsChainStatus.NO.toIntStatus()){
			if(systemUserSessionVO.getIsPlatform()==ShopIsPlatform.HEADQUARTERS.toIntStatus()){
				role.setDefaultType(DefaultType.SHOP.toIntStatus());
			}else if(systemUserSessionVO.getIsPlatform()==ShopIsPlatform.OWN.toIntStatus()){
				role.setDefaultType(DefaultType.WECHAT.toIntStatus());
			}
		}else if(systemUserSessionVO.getLoginType()==LoginType.SHOP.toIntType() && systemUserSessionVO.getIsChain()==IsChainStatus.YES.toIntStatus()){
			role.setDefaultType(DefaultType.CHAIN.toIntStatus());
		}
		
		
		List<Role> list = roleDAO.findAll(dtp.getStart(), dtp.getLength(), role);
		int totalCount = roleDAO.getTotalCount(role);
		return ViewObjectUtil.dataTables(list, dtp.getDraw(), totalCount);
	}

	@Override
	public ResultVO getAllWithFunction(RoleListVO roleListVO) {
		ResultVO result = new ResultVO();
		
		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO.getHash(DIYKey.getSessionHashKey(roleListVO.getSessionId()),
				SystemUserSessionVO.class);
		
		Role role = new Role();
		role.setPlatform(roleListVO.getPlatform());
		role.setSystemId(roleListVO.getSystemId());
//		if(systemUserSessionVO.getLoginType()==LoginType.SHOP.toIntType()){
//			role.setDefaultType(systemUserSessionVO.getIsChain());
//		}
		
		if(systemUserSessionVO.getLoginType()==LoginType.SHOP.toIntType() && systemUserSessionVO.getIsChain()==IsChainStatus.NO.toIntStatus()){
			if(systemUserSessionVO.getIsPlatform()==ShopIsPlatform.HEADQUARTERS.toIntStatus()){
				role.setDefaultType(DefaultType.SHOP.toIntStatus());
			}else if(systemUserSessionVO.getIsPlatform()==ShopIsPlatform.OWN.toIntStatus()){
				role.setDefaultType(DefaultType.WECHAT.toIntStatus());
			}
		}else if(systemUserSessionVO.getLoginType()==LoginType.SHOP.toIntType() && systemUserSessionVO.getIsChain()==IsChainStatus.YES.toIntStatus()){
			role.setDefaultType(DefaultType.CHAIN.toIntStatus());
		}
		
		List<RoleListBO> roleListBOs = roleDAO.getAllWithFunction(role);

		Set<String> ids = new TreeSet<String>();
		if (StringUtils.isNotBlank(roleListVO.getSystemUserId())) {
			List<SystemUserRole> systemUserRoles = systemUserRoleDAO.getSystemUserRole(roleListVO.getSystemUserId());
			ids = systemUserRoles.stream().map(SystemUserRole::getRoleId).collect(Collectors.toSet());
		}
		for (RoleListBO roleListBO : roleListBOs) {
			if (ids.contains(roleListBO.getId())) {
				roleListBO.setIsSelect(1);
			} else {
				roleListBO.setIsSelect(0);
			}
		}

		result.setData(roleListBOs);
		return result;
	}

	@Override
	public ResultVO getAll(String sessionId) {
		ResultVO result = new ResultVO();

		SystemUserSessionVO systemUserSessionVO = systemUserCacheDAO.getHash(DIYKey.getSessionHashKey(sessionId),
				SystemUserSessionVO.class);
		Role role = new Role();
		role.setPlatform(systemUserSessionVO.getLoginType());
		role.setSystemId(systemUserSessionVO.getSystemId());
		role.setDefaultType(systemUserSessionVO.getIsChain());
		List<Role> data = roleDAO.getAll(role);

		result.setData(data);
		return result;

	}

	@Override
	public ResultVO findById(String id) {
		ResultVO resultVO = new ResultVO();
		Role role = roleDAO.query(id);
		if (role == null) {
			throw new RoleNotFoundException("该角色不存在！");
		}
		resultVO.setData(role);
		return resultVO;
	}

	@Override
	public ResultVO add(RoleAEVO roleAdd) {
		SystemUserType.toValue(roleAdd.getPlatform().intValue());
		Role role = new Role();
		BeanUtils.copyProperties(roleAdd, role);

		ResultVO result = new ResultVO();
		Long index = roleCacheDAO.incr(DIYKey.getRoleCodeStringKey());
		String code = OrderNumberUtils.getSystemCode(OrderNumberUtils.ROLE_NUMBER_PREFIX, index.intValue());
		role.setCode(code);
		
		if(roleAdd.getIsDefault()!=null){
			if(roleAdd.getPlatform()==SystemUserType.SHOP.toIntStatus() && Is.YES.toIntValue()==roleAdd.getIsDefault()){
				int count=roleDAO.getIsDefaultCount(roleAdd.getDefaultType());
				if(count>0){
					throw new ShopDefaultRoleIsExistException("默认角色已经存在");
				}
			}
		}
		
		result.setData(roleDAO.insert(role));
		return result;
	}

	@Override
	public ResultVO addByPlatform(RoleAEVO roleAdd) {
		SystemUserType.toValue(roleAdd.getPlatform().intValue());
		Role role = new Role();
		BeanUtils.copyProperties(roleAdd, role);

		ResultVO result = new ResultVO();
		Long index = roleCacheDAO.incr(DIYKey.getRoleCodeStringKey());
		String code = OrderNumberUtils.getSystemCode(OrderNumberUtils.ROLE_NUMBER_PREFIX, index.intValue());
		role.setCode(code);
		result.setData(roleDAO.insert(role));
		return result;
	}

	@Override
	@Transactional
	public ResultVO delete(String id) {
		ResultVO result = new ResultVO();
		systemUserRoleDAO.deleteByRoleId(id);
		roleFunctionDAO.deleteByRoleId(id);
		roleDAO.delete(id);
		return result;
	}

	@Override
	public ResultVO edit(String id, RoleAEVO roleEdit) {
		ResultVO resultVO = new ResultVO();
		Role role = new Role();
		BeanUtils.copyProperties(roleEdit, role);
		resultVO.setData(roleDAO.update(role));
		return resultVO;
	}

	@Override
	public int getCountByRoleId(String roleId) {
		return systemUserRoleDAO.getCountByRoleId(roleId);
	}

	@Override
	public ResultVO addRoleFunction(RoleFunctionAddVO roleFunctionAddVO) {
		ResultVO result = new ResultVO();
		String roleId = roleFunctionAddVO.getRoleId();
		List<RoleFunction> roleFunctions = new ArrayList<RoleFunction>();
		for (String functionId : roleFunctionAddVO.getFunctionIds()) {
			RoleFunction roleFunction = new RoleFunction();
			roleFunction.setFunctionId(functionId);
			roleFunction.setRoleId(roleId);
			roleFunctions.add(roleFunction);
		}

		int count = roleFunctionDAO.getTotalCountByRole(roleId);
		if (count > 0) {
			roleFunctionDAO.deleteByRoleId(roleId);
		}
		int data = roleFunctionDAO.batchInsert(roleFunctions);
		result.setData(data);
		return result;
	}

}
